package com.mojian.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mojian.entity.PointsRecord;
import com.mojian.entity.UserPoints;
import com.mojian.exception.ServiceException;
import com.mojian.mapper.PointsRecordMapper;
import com.mojian.mapper.UserPointsMapper;
import com.mojian.service.PointsService;
import com.mojian.utils.PageUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 积分服务实现类
 */
@Service
@RequiredArgsConstructor
public class PointsServiceImpl implements PointsService {

    private final UserPointsMapper userPointsMapper;
    private final PointsRecordMapper pointsRecordMapper;
    private final JdbcTemplate jdbcTemplate;

    @Override
    public UserPoints getUserPoints() {
        // 获取当前登录用户的积分信息
        Long userId = StpUtil.getLoginIdAsLong();
        return getUserPointsById(userId);
    }
    
    @Override
    public UserPoints getUserPointsById(Long userId) {
        System.out.println("查询用户ID为" + userId + "的积分信息");
        
        if (userId == null) {
            throw new ServiceException("用户ID不能为空");
        }
        
        try {
            // 查询用户积分信息
            UserPoints userPoints = userPointsMapper.selectOne(
                new LambdaQueryWrapper<UserPoints>().eq(UserPoints::getUserId, userId)
            );
            
            // 如果用户没有积分记录，创建一个初始记录
            if (userPoints == null) {
                userPoints = new UserPoints();
                userPoints.setUserId(userId);
                userPoints.setPoints(0);
                userPoints.setTotalEarned(0);
                userPoints.setTotalConsumed(0);
                userPointsMapper.insert(userPoints);
                System.out.println("为用户ID " + userId + " 创建了新的积分记录");
            } else {
                System.out.println("找到用户ID " + userId + " 的积分记录: 当前积分=" + userPoints.getPoints() + 
                                  ", 累计获得=" + userPoints.getTotalEarned() + 
                                  ", 累计消费=" + userPoints.getTotalConsumed());
            }
            
            return userPoints;
        } catch (Exception e) {
            System.err.println("查询用户积分信息出错: " + e.getMessage());
            e.printStackTrace();
            throw new ServiceException("查询积分信息失败: " + e.getMessage());
        }
    }

    @Override
    public Page<PointsRecord> getPointsRecords(Integer pageNum, Integer pageSize, Long userId) {
        // 如果userId为空，使用当前登录用户ID
        if (userId == null) {
            userId = StpUtil.getLoginIdAsLong();
        }
        
        System.out.println("获取积分记录 - 用户ID: " + userId + ", 页码: " + pageNum + ", 每页数量: " + pageSize);
        
        Page<PointsRecord> page = new Page<>(pageNum, pageSize);
        Page<PointsRecord> result = pointsRecordMapper.getPointsRecords(page, userId);
        
        System.out.println("查询结果 - 总记录数: " + (result != null ? result.getTotal() : "null") + 
                          ", 记录数量: " + (result != null && result.getRecords() != null ? result.getRecords().size() : "null"));
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addPoints(Long userId, Integer points, Integer type, Long relatedId, String description) {
        if (points <= 0) {
            throw new ServiceException("积分必须大于0");
        }
        
        // 获取用户积分信息
        UserPoints userPoints = getUserPointsByUserId(userId);
        
        // 更新用户积分
        userPoints.setPoints(userPoints.getPoints() + points);
        userPoints.setTotalEarned(userPoints.getTotalEarned() + points);
        userPointsMapper.updateById(userPoints);
        
        // 记录积分变动
        PointsRecord record = new PointsRecord();
        record.setUserId(userId);
        record.setPoints(points);
        record.setBalance(userPoints.getPoints());
        record.setType(type);
        record.setRelatedId(relatedId);
        record.setDescription(description);
        pointsRecordMapper.insert(record);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean consumePoints(Long userId, Integer points, Integer type, Long relatedId, String description) {
        if (points <= 0) {
            throw new ServiceException("积分必须大于0");
        }
        
        // 获取用户积分信息
        UserPoints userPoints = getUserPointsByUserId(userId);
        
        // 检查积分是否足够
        if (userPoints.getPoints() < points) {
            throw new ServiceException("积分不足");
        }
        
        // 更新用户积分
        userPoints.setPoints(userPoints.getPoints() - points);
        userPoints.setTotalConsumed(userPoints.getTotalConsumed() + points);
        userPointsMapper.updateById(userPoints);
        
        // 记录积分变动
        PointsRecord record = new PointsRecord();
        record.setUserId(userId);
        record.setPoints(-points); // 消费为负数
        record.setBalance(userPoints.getPoints());
        record.setType(type);
        record.setRelatedId(relatedId);
        record.setDescription(description);
        pointsRecordMapper.insert(record);
        
        return true;
    }

    @Override
    public boolean signInReward(Long userId) {
        // 签到奖励10积分
        return addPoints(userId, 10, 1, null, "每日签到奖励");
    }

    @Override
    public boolean hasEnoughPoints(Long userId, Integer points) {
        UserPoints userPoints = getUserPointsByUserId(userId);
        return userPoints.getPoints() >= points;
    }
    
    /**
     * 根据用户ID获取积分信息
     */
    private UserPoints getUserPointsByUserId(Long userId) {
        UserPoints userPoints = userPointsMapper.selectOne(
            new LambdaQueryWrapper<UserPoints>().eq(UserPoints::getUserId, userId)
        );
        
        // 如果用户没有积分记录，创建一个初始记录
        if (userPoints == null) {
            userPoints = new UserPoints();
            userPoints.setUserId(userId);
            userPoints.setPoints(0);
            userPoints.setTotalEarned(0);
            userPoints.setTotalConsumed(0);
            userPointsMapper.insert(userPoints);
        }
        
        return userPoints;
    }

    @Override
    public List<Map<String, Object>> debugGetAllPointsRecords() {
        try {
            // 直接使用JDBC查询points_record表
            String sql = "SELECT * FROM points_record ORDER BY create_time DESC";
            List<Map<String, Object>> records = jdbcTemplate.queryForList(sql);
            System.out.println("调试: 直接查询到 " + records.size() + " 条积分记录");
            
            // 打印前5条记录的内容
            int count = 0;
            for (Map<String, Object> record : records) {
                if (count++ < 5) {
                    System.out.println("记录 #" + count + ": " + record);
                }
            }
            
            return records;
        } catch (Exception e) {
            System.err.println("调试查询错误: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    @Override
    public List<PointsRecord> debugGetUserPointsRecords(Long userId) {
        try {
            // 使用Mybatis Plus直接查询
            LambdaQueryWrapper<PointsRecord> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(PointsRecord::getUserId, userId);
            queryWrapper.orderByDesc(PointsRecord::getCreateTime);
            
            List<PointsRecord> records = pointsRecordMapper.selectList(queryWrapper);
            System.out.println("调试: 用户ID " + userId + " 的积分记录查询结果: " + (records != null ? records.size() : "null") + " 条");
            
            // 打印前几条记录
            if (records != null && !records.isEmpty()) {
                for (int i = 0; i < Math.min(records.size(), 3); i++) {
                    System.out.println("记录 #" + (i+1) + ": " + records.get(i));
                }
            }
            
            return records;
        } catch (Exception e) {
            System.err.println("调试查询错误: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
} 